package com.xianggu.agency.jdkProxy;

import org.springframework.core.io.DefaultResourceLoader;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author chengjy
 * @date 2025/3/18
 */
public class XiangGuProxyFactory {

    private ClassLoader classLoader = new DefaultResourceLoader().getClassLoader();

    private String packageName = "com.xianggu.insight.proxy";

    String createPath = "D:\\临时文件夹呀呀呀呀\\动态代理生成文件";

    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    private File createJavaFile(Class aClass) throws IOException {

        String fileName = getClassName(aClass);

        StringBuilder methodText = new StringBuilder();
        for (Method method : aClass.getMethods()) {
            String methodBody = JdkProxyFunctionUtils.joinMethod(method);
            methodText.append(methodBody);
        }

        String context ="package "+ packageName +"; \n"+
                "\n" +
                "import "+ aClass.getName() +";\n" +
                "import com.xianggu.agency.jdkProxy.XiangGuProxy;\n" +
                "import java.lang.reflect.Method;"+
                "\n" +
                "/**\n" +
                " * @author chengjy\n" +
                " * @date 2025/3/18\n" +
                " */\n" +
                "public class "+fileName+" implements "+ aClass.getSimpleName() +" {\n" +
                "    private XiangGuProxy handler;\n" +
                methodText.toString()+
                "\n" +
                "}\n";
        File file = new File( createPath + "\\" + fileName + ".java");
        Files.writeString(file.toPath(), context);
        return file;
    }

    private String getClassName(Class aClass) throws IOException {
        return aClass.getSimpleName()+ "$proxy0" + atomicInteger.incrementAndGet();
    }

    private Object createJava(String fileName, XiangGuProxy proxy) throws IOException {
        try {
            if (fileName.contains(".java")) {
                fileName = fileName.replace(".java", "");
            }

            Class<?> aClass = classLoader.loadClass(fileName);
            Constructor<?>[] constructors = aClass.getConstructors();
            constructors[0].setAccessible(true);
            Object object = constructors[0].newInstance();
            Field handler = aClass.getDeclaredField("handler");
            handler.setAccessible(true);
            // 给代理执行函数赋值
            handler.set(object, proxy);
            return object;
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    public static Object createProxyObject(Class<?> tClass , XiangGuProxy proxy) throws IOException {
        // 创建一个被代理对象
        XiangGuProxyFactory myInterfaceFactory = new XiangGuProxyFactory();
        // 本地生成Java文件
        File javaFile = myInterfaceFactory.createJavaFile(tClass );
        // 编译Java文件输出在当前项目下target\classes
        Compiler.complie(javaFile);
        System.out.println("执行成功！"+ javaFile.getPath());
        if (javaFile.delete()) {
            System.out.println("删除成功！"+ javaFile.getPath());
        }
        return myInterfaceFactory.createJava(myInterfaceFactory.packageName + "." + javaFile.getName() , proxy);
    }

}
